﻿using Microsoft.Extensions.Configuration;
using Prism.Commands;
using Prism.Mvvm;
using Prism.Regions;
using Prism.Services.Dialogs;
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Xml.Linq;
using TransformerManager.WPF.Common.Utils;
using hc = HandyControl.Controls;

namespace TransformerManager.WPF.OptionItemModule.ViewModels
{
    public class OptionItemViewModel : BindableBase, INavigationAware
    {
        private readonly IDialogService _dialogService;
        private readonly IConfiguration _configuration;
        public OptionItemViewModel(IDialogService dialogService, IConfiguration configuration)
        {
            _dialogService = dialogService;
            _configuration = configuration;

            InitCmd();
        }

        #region Command的定义

        // 基本信息
        public DelegateCommand ProjectStatusCmd { set; get; }
        public DelegateCommand ApplicationTypeCmd { set; get; }
        public DelegateCommand VectorGroupSymCmd { set; get; }
        public DelegateCommand ProdTagCmd { set; get; }
        public DelegateCommand HousingCmd { set; get; }
        public DelegateCommand InsulationMaterialCmd { set; get; }
        // 开关信息
        public DelegateCommand TapChangerPositionCmd { set; get; }
        public DelegateCommand OperationTypeCmd { set; get; }
        public DelegateCommand TapChangerManufacturerCmd { set; get; }
        public DelegateCommand TapChangerProdTypeCmd { set; get; }
        // 套管信息
        public DelegateCommand BushingProdTypeCmd { set; get; }
        public DelegateCommand BushingInsulatorColorCmd { set; get; }
        public DelegateCommand BushingRefStandardCmd { set; get; }
        public DelegateCommand BushingManufacturerCmd { set; get; }
        // 油箱信息
        public DelegateCommand TankShapeCmd { set; get; }
        public DelegateCommand TankFrameTypeCmd { set; get; }
        public DelegateCommand TankRadButterflyValveTypeCmd { set; get; }
        public DelegateCommand TankOltcIndentCmd { set; get; }
        public DelegateCommand TankHVLVIndentCmd { set; get; }
        public DelegateCommand TankActbDomeCmd { set; get; }
        public DelegateCommand TankOctbDomeCmd { set; get; }
        // 储油柜信息
        public DelegateCommand ConservatorTypeCmd { set; get; }
        public DelegateCommand ConservatorDimensionCmd { set; get; }
        // 冷却信息
        public DelegateCommand CoolingTypeCmd { set; get; }
        public DelegateCommand CoolingLayoutCmd { set; get; }
        public DelegateCommand RadiatorManufacturerCmd { set; get; }
        public DelegateCommand FanManufacturerCmd { set; get; }
        public DelegateCommand CoolerManufacturerCmd { set; get; }
        // 附件信息
        public DelegateCommand BoltMaterialCmd { set; get; }
        public DelegateCommand SealMaterialCmd { set; get; }
        public DelegateCommand AccessoryEquNameCmd { set; get; }
        // 引线信息
        public DelegateCommand HVOutletCmd { set; get; }
        public DelegateCommand HVROutletCmd { set; get; }
        public DelegateCommand LVOutletCmd { set; get; }
        public DelegateCommand MVOutletCmd { set; get; }
        public DelegateCommand BushingPosCmd { set; get; }
        public DelegateCommand LeadNameCmd { set; get; }
        public DelegateCommand LeadTypeCmd { set; get; }
        public DelegateCommand LeadDimensionTypeCmd { set; get; }
        public DelegateCommand LeadSiCmd { set; get; }
        // HVR线圈信息
        public DelegateCommand HVRWindingTypeCmd { set; get; }
        public DelegateCommand HVRWindingDirectionCmd { set; get; }
        public DelegateCommand HVRStripNumberCmd { set; get; }
        public DelegateCommand HVRSpacerNumberCmd { set; get; }
        public DelegateCommand HVRSpacerWidthCmd { set; get; }
        public DelegateCommand HVRConductorNumberCmd { set; get; }
        public DelegateCommand HVRStepNumberCmd { set; get; }
        public DelegateCommand HVRTopKsNumberCmd { set; get; }
        public DelegateCommand HVRAngleRingNumberCmd { set; get; }
        // Disc线圈信息
        public DelegateCommand DiscWindingTypeCmd { set; get; }
        public DelegateCommand DiscWindingNameCmd { set; get; }
        public DelegateCommand DiscWindingDirectionCmd { set; get; }
        public DelegateCommand DiscStripNumberCmd { set; get; }
        public DelegateCommand DiscSpacerNumberCmd { set; get; }
        public DelegateCommand DiscSpacerWidthCmd { set; get; }
        public DelegateCommand DiscConductorNumberCmd { set; get; }
        public DelegateCommand DiscOilDeflectorNumberCmd { set; get; }
        public DelegateCommand DiscConductorStrandNumberCmd { set; get; }
        // Layer线圈信息
        public DelegateCommand LayerWindingNameCmd { set; get; }
        public DelegateCommand LayerWindingTypeCmd { set; get; }
        public DelegateCommand LayerInnerLayerDirectionCmd { set; get; }
        public DelegateCommand LayerStripNumberCmd { set; get; }
        public DelegateCommand LayerSpacerNumberCmd { set; get; }
        public DelegateCommand LayerSpacerWidthCmd { set; get; }
        public DelegateCommand LayerAsialConductorNumberCmd { set; get; }
        public DelegateCommand LayerRadialConductorNumberCmd { set; get; }
        public DelegateCommand LayerOilDeflectorNumberCmd { set; get; }
        public DelegateCommand LayerInnerCylinderNumberCmd { set; get; }
        // 器身信息
        public DelegateCommand ActivePartStripNumberCmd { set; get; }
        public DelegateCommand ActivePartSpacerNumberCmd { set; get; }
        public DelegateCommand ActivePartRatedVotageCmd { set; get; }
        public DelegateCommand ActivePartWindingNumberCmd { set; get; }
        public DelegateCommand ActivePartHVRTypeCmd { set; get; }
        public DelegateCommand ActivePartInnestWindingTypeCmd { set; get; }
        public DelegateCommand ActivePartHVACCmd { set; get; }
        #endregion

        #region 函数的定义

        private void InitCmd()
        {
            // 基本信息

            ProjectStatusCmd = new DelegateCommand( async () =>
            {
                await EditXmlFile("BasicInfos.xml", "ProjectStatus");
            });

            ApplicationTypeCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("BasicInfos.xml", "ApplicationType");
            });

            VectorGroupSymCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("BasicInfos.xml", "VectorGroupSym");
            });

            ProdTagCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("BasicInfos.xml", "ProdTag");
            });

            HousingCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("BasicInfos.xml", "Housing");
            });

            InsulationMaterialCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("BasicInfos.xml", "InsulationMaterial");
            });

            // 开关信息

            TapChangerPositionCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("TapChanger.xml", "TapChangerPosition");
            });

            OperationTypeCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("TapChanger.xml", "OperationType");
            });

            TapChangerManufacturerCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("TapChanger.xml", "Manufacturer");
            });

            TapChangerProdTypeCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("TapChanger.xml", "TapChangerProdType");
            });

            // 套管信息
            BushingProdTypeCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("Bushing.xml", "BushingProdType");
            });

            BushingInsulatorColorCmd = new DelegateCommand(async () =>
             {
                 await EditXmlFile("Bushing.xml", "InsulatorColor");
             });

            BushingRefStandardCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("Bushing.xml", "RefStandard");
            });

            BushingManufacturerCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("Bushing.xml", "Manufacturer");
            });

            // 油箱信息
            TankShapeCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("Tank.xml", "TankShape");
            });

            TankFrameTypeCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("Tank.xml", "FrameType");
            });

            TankFrameTypeCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("Tank.xml", "FrameType");
            });

            TankRadButterflyValveTypeCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("Tank.xml", "RadButterflyValveType");
            });

            TankOltcIndentCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("Tank.xml", "OltcIndent");
            });

            TankHVLVIndentCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("Tank.xml", "HVLVIndent");
            });

            TankActbDomeCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("Tank.xml", "ActbDome");
            });

            TankOctbDomeCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("Tank.xml", "OctbDome");
            });

            // 储油柜信息
            ConservatorTypeCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("Conservator.xml", "ConservatorType");
            });

            ConservatorDimensionCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("Conservator.xml", "Dimension");
            });

            // 冷却信息
            CoolingTypeCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("CoolingSystem.xml", "CoolingType");
            });
            CoolingLayoutCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("CoolingSystem.xml", "CoolingLayout");
            });
            RadiatorManufacturerCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("CoolingSystem.xml", "RadiatorManufacturer");
            });
            FanManufacturerCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("CoolingSystem.xml", "FanManufacturer");
            });
            CoolerManufacturerCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("CoolingSystem.xml", "CoolerManufacturer");
            });

            // 附件信息
            BoltMaterialCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("Accessories.xml", "BoltMaterial");
            });
            SealMaterialCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("Accessories.xml", "SealMaterial");
            });
            AccessoryEquNameCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("AccesstoryEquipments.xml", "AccessoryEquName");
            });

            // 引线信息
            HVOutletCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("Lead.xml", "HVOutlet");
            });
            HVROutletCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("Lead.xml", "HVROutlet");
            });
            LVOutletCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("Lead.xml", "LVOutlet");
            });
            MVOutletCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("Lead.xml", "MVOutlet");
            });
            BushingPosCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("Lead.xml", "BushingPos");
            });
            LeadNameCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("LeadConnectors.xml", "LeadName");
            });
            LeadTypeCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("LeadConnectors.xml", "LeadType");
            });
            LeadDimensionTypeCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("LeadConnectors.xml", "LeadDimensionType");
            });
            LeadSiCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("LeadConnectors.xml", "Si");
            });

            // HVR线圈信息
            HVRWindingTypeCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("HVRWinding.xml", "HVRWindingType");
            });
            HVRWindingDirectionCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("HVRWinding.xml", "WindingDirection");
            });
            HVRStripNumberCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("HVRWinding.xml", "StripNumber");
            });
            HVRSpacerNumberCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("HVRWinding.xml", "SpacerNumber");
            });
            HVRSpacerWidthCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("HVRWinding.xml", "SpacerWidth");
            });
            HVRConductorNumberCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("HVRWinding.xml", "ConductorNumber");
            });
            HVRStepNumberCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("HVRWinding.xml", "HVRStepNumber");
            });
            HVRTopKsNumberCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("HVRWinding.xml", "TopKsNumber");
            });
            HVRAngleRingNumberCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("HVRWinding.xml", "AngleRingNumber");
            });

            // Disc线圈信息
            DiscWindingTypeCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("DiscWinding.xml", "DiscWindingType");
            });

            DiscWindingNameCmd= new DelegateCommand(async () =>
            {
                await EditXmlFile("DiscWinding.xml", "WindingName");
            });

            DiscWindingDirectionCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("DiscWinding.xml", "WindingDirection");
            });

            DiscStripNumberCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("DiscWinding.xml", "StripNumber");
            });

            DiscSpacerNumberCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("DiscWinding.xml", "SpacerNumber");
            });

            DiscSpacerWidthCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("DiscWinding.xml", "SpacerWidth");
            });

            DiscConductorNumberCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("DiscWinding.xml", "ConductorNumber");
            });

            DiscOilDeflectorNumberCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("DiscWinding.xml", "OilDeflectorNumber");
            });

            DiscConductorStrandNumberCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("DiscWinding.xml", "ConductorStrandNumber");
            });

            // Layer线圈信息
            LayerWindingNameCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("LayerWinding.xml", "WindingName");
            });
            LayerWindingTypeCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("LayerWinding.xml", "LayerWindingType");
            });
            LayerInnerLayerDirectionCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("LayerWinding.xml", "InnerLayerDirection");
            });
            LayerStripNumberCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("LayerWinding.xml", "StripNumber");
            });
            LayerSpacerNumberCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("LayerWinding.xml", "SpacerNumber");
            });
            LayerSpacerWidthCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("LayerWinding.xml", "SpacerWidth");
            });
            LayerAsialConductorNumberCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("LayerWinding.xml", "AsialConductorNumber");
            });
            LayerRadialConductorNumberCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("LayerWinding.xml", "RadialConductorNumber");
            });
            LayerOilDeflectorNumberCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("LayerWinding.xml", "OilDeflectorNumber");
            });
            LayerInnerCylinderNumberCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("LayerWinding.xml", "InnerCylinderNumber");
            });

            // 器身信息
            ActivePartStripNumberCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("ActivePart.xml", "StripNumber");
            });
            ActivePartSpacerNumberCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("ActivePart.xml", "SpacerNumber");
            });
            ActivePartRatedVotageCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("ActivePart.xml", "RatedVotage");
            });
            ActivePartWindingNumberCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("ActivePart.xml", "WindingNumber");
            });
            ActivePartHVRTypeCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("ActivePart.xml", "HVRType");
            });
            ActivePartInnestWindingTypeCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("ActivePart.xml", "InnestWindingType");
            });
            ActivePartHVACCmd = new DelegateCommand(async () =>
            {
                await EditXmlFile("ActivePart.xml", "HVAC");
            });
        }

        private async Task EditXmlFile(string fileName, string menuName)
        {
            try
            {
                string filePath = $"./XML/{fileName}";

                XElement xmlElem = XElement.Load(filePath);

                XElement xelem = (from e in xmlElem.Elements("MenuItems")
                                  where e.Attribute("MenuName").Value.Equals(menuName)
                                  select e).FirstOrDefault();

                var optItemObjs = from ele in xelem.Elements("Item")
                                  select new OptionItemObject
                                  {
                                      ENName = ele.Element("ENName").Value,
                                      CNName = ele.Element("CNName").Value,
                                  };

                DialogParameters dialogParams = new DialogParameters()
                {
                    {"xmlFileName", fileName },
                    {"elementName", menuName },
                    {"OptionItemObjects", new ObservableCollection<OptionItemObject>(optItemObjs)}
                };

                ObservableCollection<OptionItemObject> itemObjects
                    = new ObservableCollection<OptionItemObject>();
                bool isCanceled = false;
                _dialogService.ShowDialog("OptionItemDialog", dialogParams, r =>
                {
                    if (r.Result == ButtonResult.OK)
                    {
                        itemObjects = r.Parameters
                        .GetValue<ObservableCollection<OptionItemObject>>("UpdatedOptItems");
                    }
                    else
                    {
                        isCanceled = true;
                    }
                });

                if (isCanceled)
                {
                    return;
                }

                if (itemObjects == null || itemObjects.Count == 0)
                {
                    hc.Growl.Error($"响应信息：错误!编辑对象为空，请确认数据文件是否正常!", "Notification");
                    return;
                }

                // 构建相同的MenuItems节点
                XElement menuItemsElem = new XElement("MenuItems", new XAttribute("MenuName", menuName));

                foreach (var item in itemObjects)
                {
                    XElement itemElem = new XElement("Item",
                        new XElement("ENName", item.ENName),
                        new XElement("CNName", item.CNName));
                    menuItemsElem.Add(itemElem);
                }

                xelem.ReplaceWith(menuItemsElem);

                await Task.Factory.StartNew(() =>
                {
                    xmlElem.Save(filePath);
                    // 数据备份
                    if(!Directory.Exists(_configuration["XmlDataBackup"]))
                    {
                        Directory.CreateDirectory(_configuration["XmlDataBackup"]);
                    }
                    xmlElem.Save($"{ _configuration["XmlDataBackup"]}/{fileName}");

                    hc.Growl.Success($"响应信息：{fileName}已更新!", "Notification");
                });
            }
            catch(Exception e)
            {
                hc.Growl.Error($"异常信息：错误! {e.Message}", "Notification");
            }
        }

        #endregion


        #region 接口的实现

        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            return true;
        }

        public void OnNavigatedFrom(NavigationContext navigationContext)
        {

        }

        public void OnNavigatedTo(NavigationContext navigationContext)
        {

        }

        #endregion
    }
}
